using System;
using System.Collections.Generic;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
namespace Build
{
    [System.Serializable]
    public class BuildException : Exception
    {
        public BuildException() { }
        public BuildException(string message) : base(message) { }
        
    }
    public interface IGloalInfomation
    {
        string Description { get; }
        string Version { get; }
        bool IsDebugBuilderLibrary { set; get; }
    }
    public interface IAction
    {
        void Building();
        void Clean();
    }
    public enum OsTypes
    {
        Linux,
        Windows,
        Unix,
        Mac,
        UnKnown,
    };
    internal static class OsInfomation
    {
        public static OsTypes OsHostType
        {
            get
            {
                var o = Environment.OSVersion.Platform.ToString();
                if (o.ToUpper() == "WIN32NT")
                {
                    return OsTypes.Windows;
                }
                else if (o.ToUpper() == "LINUX")
                {
                    return OsTypes.Linux;
                }
                else if (o.ToUpper() == "MAC")
                {
                    return OsTypes.Mac;
                }
                else if (o.ToUpper() == "UNIX")
                {
                    return OsTypes.Unix;
                }
                else
                {
                    return OsTypes.UnKnown;
                }
            }
        }
    }
    public static class RunCommand
    {
        public static string  Run(string cmd, params string[] d)
        {
            Process proc = new Process();
           // proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.FileName = cmd;
            proc.StartInfo.UseShellExecute = false;
            /*proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.RedirectStandardInput = true;
            proc.StartInfo.RedirectStandardOutput = true;*/
            StringBuilder allstring = new StringBuilder();
            
            foreach (var item in d)
            {
                allstring.Append(item + " ");
            }
            Console.Write("命令行:"+cmd + " " + allstring.ToString());
            //proc.StandardInput.WriteLine(allstring);
            proc.StartInfo.Arguments = allstring.ToString();
            //string outStr="编译器输出:";
            //proc.OutputDataReceived += ((object sender, DataReceivedEventArgs e) =>
            // {
            //    outStr += e.Data;
            // });
            proc.Start();
            
            proc.WaitForExit();
            
            proc.Close();
            return outStr;
        }

        
    }
    namespace CppBuild
    {
        /*public enum ComplierTypes
        {
            GCC = 1,
            MSVC = 2,
            ARMCC = 3,
            ICC = 4
        };*/
        public enum CStandardTypes
        {
            ISOC90,
            ISOC99,
            ISOC11,
            GNUC99,
            GNUC11
        };
        public enum CxxStandardTypes
        {
            ISOCxx1998 = 1,
            ISOCxx2011_0x = 2,
            ISOCxx2011_11 = 3,
            GNUISO2011_0x = 4,
            GNUISO2011_11 = 5,
        };
        public enum CxxStandardLibrarys
        {
            LibStdCxx = 1,
            LibCxx = 2,
        };
        public enum OutFileTypes
        {
            Executable,
            StaticLibrary,
            DynamicLibrary,
        }
        public abstract class GccCppModule : IGloalInfomation, IAction
        {
            public enum OptimizationTypes
            {
                O0,
                O1,
                O2,
                O3,
                Os,
                Ofast,
                Og,
            }
            public OptimizationTypes OptimizationType { get; set; }


            public abstract string Version { get; }
            public abstract string Description { get; }

            public bool IsDebugBuilderLibrary { get; set; }
            //ASM
            private List<string> _AsmDefineList;
            public List<string> AsmDefineList { get { return _AsmDefineList; } }
            public void AddAsmDefine(params string[] d)
            {
                foreach (var item in d)
                {
                    this.AsmDefineList.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("ASM:添加定义:{0}", item);
                }
            }

            private List<string> _AsmIncludePath;
            public List<string> AsmIncludePath { get { return _AsmIncludePath; } }
            /// <summary>
            /// 添加ASM的头文件路径
            /// </summary>
            /// <param name="d"></param>
            public void AddAsmIncludePath(params string[] d)
            {
                foreach (var item in d)
                {
                    if (Directory.Exists(item) == false)
                        throw new DirectoryNotFoundException(string.Format("{0}目录未找到!", item));
                    this.AsmIncludePath.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("ASM:添加头文件路径:{0}", item);
                }
            }

            private List<String> _AsmOtherFlag;
            public List<String> AsmOtherFlag { get { return _AsmOtherFlag; } }
            public void AddAsmOtherFlag(params string[] d)
            {
                foreach (var item in d)
                {
                    this.AsmOtherFlag.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("ASM:添加其他标志量:{0}", item);
                }
            }

            //C 
            private List<string> _CDefineList;
            public List<String> CDefineList { get { return _CDefineList; } }
            /// <summary>
            /// 添加C语言的宏定义，例如:DEBUG=1
            /// </summary>
            /// <param name="d"></param>
            public void AddCDefineList(params string[] d)
            {
                foreach (var item in d)
                {
                    this.CDefineList.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("C语言:添加定义:{0}", item);
                }
            }

            private List<String> _CIncludePath;
            public List<String> CIncludePath { get { return _CIncludePath; } }
            /// <summary>
            /// 添加C语言的头文件路径
            /// </summary>
            /// <param name="d"></param>
            public void AddCIncludePath(params string[] d)
            {
                foreach (var item in d)
                {
                    if (Directory.Exists(item) == false)
                        throw new DirectoryNotFoundException(string.Format("{0}目录未找到!", item));
                    this.CIncludePath.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("C语言:添加头文件:{0}", item);
                }
            }

            public CStandardTypes CStandard { get; set; } 

            private List<String> _CFile;
            public List<String> CFile { get { return _CFile; }set { _CFile = value; } }
            /// <summary>
            /// 添加Cfile
            /// </summary>
            /// <param name="file"></param>
            /// <param name="filter"></param>
            public void AddCFile(params string[] file)
            {
                foreach (var item in file)
                {
                    if (File.Exists(item) == false)
                        throw new FileNotFoundException(item + " 文件不存在！");
                    CFile.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("C语言:添加文件:" + item);

                }

            }

            //Cxx
            private List<String> _CxxDefineList;
            public List<String> CxxDefineList { get { return _CxxDefineList; } }
            public void AddCxxDefineList(params string[] d)
            {
                foreach (var item in d)
                {
                    this.CxxDefineList.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("C++语言:添加定义:{0}", item);
                }
            }

            private List<String> _CxxIncludePath;
            public List<String> CxxIncludePath { get { return _CxxIncludePath; } }
            public void AddCxxIncludePath(params string[] d)
            {
                foreach (var item in d)
                {
                    if (Directory.Exists(item) == false)
                        throw new DirectoryNotFoundException(string.Format("{0}目录未找到!", item));
                    this.CxxIncludePath.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("C++语言:添加头文件:{0}", item);
                }
            }


            public CxxStandardTypes CxxStandard { get; set; } 
            public CxxStandardLibrarys CxxStandardLibrary { get; set; }
            public bool IsWarning { get; set; }

            private List<String> _CxxFile;
            public List<String> CxxFile;
            public void AddCxxFile(string[] file)
            {
                foreach (var item in file)
                {
                    if (File.Exists(item) == false)
                        throw new FileNotFoundException(item + " 文件不存在！");
                    CFile.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("Cxx语言:添加文件:" + item);

                }

            }

            //库
            private List<String> _LibraryPath;
            public List<String> LibraryPath { get { return _LibraryPath; } }
            public void AddLibraryPath(params string[] d)
            {
                foreach (var item in d)
                {
                    if (File.Exists(item) == false)
                        throw new FileNotFoundException(string.Format("{0}文件未找到!", item));
                    this.LibraryPath.Add(item);
                    if (this.IsDebugBuilderLibrary == true)
                        Console.WriteLine("添加库文件:{0}", item);
                }
            }

            //linker
            public FileInfo LinkerFile { get; set; }


            //输出
            public string OutBuildPath { get; set; }
            private string _MapFile = string.Empty;
            public string MapFile {
                get { return _MapFile; }
                set { _MapFile = value; }

            }
            public bool IsOutPutMapFile { get; set; }
            public bool IsOutAsmFile { get; set; }
            public string OutFileName { get; set; }
            public abstract OutFileTypes OutFileType { get; set; }

            public GccCppModule()
            {
                this._AsmDefineList = new List<string>();
                this._AsmIncludePath = new List<string>();
                this._AsmOtherFlag = new List<string>();
                this._CDefineList = new List<string>();
                this._CIncludePath = new List<string>();
                this._CFile = new List<string>();
                this._CxxDefineList = new List<string>();
                this._CxxIncludePath = new List<string>();
                this._LibraryPath = new List<string>();


            }
            public abstract void Building();
            public abstract void BuildAll();
            public abstract void Clean();
            public abstract string ToolsPath { get; set; }
            
            
           
        }
    }
    namespace Android
    {
    }
}